<template>
  <div>
    <el-descriptions :border="true" :column="1" class="mt5 mr5 mb5 ml5">
      <el-descriptions-item>
        <template #label>
          <div style="display: flex">
            <div style="flex: 1;color: #1a1a1a !important;font-weight: bold;text-align-last: center;">
              支付方式
            </div>
          </div>
        </template>
        <div style="display: flex">
          <div
            style="flex: 0.5;color: #1a1a1a !important;font-weight: bold;text-align-last: center;">
            支付金额
          </div>
        </div>
      </el-descriptions-item>
      <el-descriptions-item
        v-for="(item, index) in payWayDictList"
        :key="index"
        min-width="220px"
      >
        <template #label>
          <div style="display: flex">
            <div style="flex: 1">
              <el-select
                v-model="payWayDictList[index].dictValue"
                :disabled="item.cssClass === 'disable' || item.disable"
                :class="item.dictValue ==='5' ? 'back-color' : ''"
                placeholder="请选择"
                style="width: 120px"
                @change="payWayChange($event, index)"
              >
                <el-option
                  v-for="dict in dictSelect"
                  :key="dict.dictValue"
                  :disabled="dict.optionDisable"
                  :label="dict.dictLabel"
                  :value="dict.dictValue"
                ></el-option>
              </el-select>
            </div>
            <div style="flex: 0.3">
              <el-tooltip
                v-if="index === 0"
                :hide-after="0"
                class="box-item"
                content="添加支付方式"
                effect="dark"
                placement="left-end"
              >
                <el-button class="ml10" type="primary" @click="addPayWay">
                  <template #icon>
                    <i-ep-plus/>
                  </template>
                </el-button>
              </el-tooltip>
              <el-tooltip
                v-else-if="!item.disable"
                :hide-after="0"
                class="box-item"
                content="删除支付方式"
                effect="dark"
                placement="left-end"
              >
                <el-button class="ml10" type="danger" @click="removePayWay(index)">
                  <template #icon>
                    <i-ep-minus/>
                  </template>
                </el-button>
              </el-tooltip>
            </div>
          </div>
        </template>
        <el-input
          v-model="payWayDictList[index].charges"
          :disabled="item.disable"
          clearable
          placeholder="请输入金额"
          type="number"
          @blur="payWayBlur()"
        >
          <template #append>元</template>
        </el-input>
      </el-descriptions-item>
    </el-descriptions>
  </div>
</template>
<script lang="ts">
export default {
  name: "PayWayList",
}
</script>

<script lang="ts" setup>
import {useDictStoreHook} from "@/store/modules/dict";

const dictStore = useDictStoreHook();
let dictDataMap = ref(dictStore.isTypeGetData("pay_way_dict"));

// 支付类型明细
const payWayDictList = ref<any>([]);

// 支付方式显示list
const dictSelect = ref<any>(dictDataMap.value["pay_way_dict"]);

const firstPayWay = {dictValue: "5", charges: 0.0} as any;

const emits = defineEmits(["payWayBlur", "setNetReceipts"]);
const props = defineProps({
  totalPrice: {
    type: Number,
    default: 0.0,
  },
  inpOrOutp: {
    type: Number,
    default: 0.0,
  },
});

// 初始化支付方式option都为可选状态
function initPayWayDictSelect() {
  dictSelect.value.forEach((pay: any) => {
    pay.optionDisable = false;
  });
}

// 定义常量，避免硬编码  预交金
const PAYMENT_METHOD_CODE = "99";

// 定义一个函数来创建支付方式对象
function createPaymentMethod(charges: number) {
  return {
    dictValue: PAYMENT_METHOD_CODE,
    charges,
    disable: true
  };
}


/**
 * 门诊、住院增加第一行的支付方式
 */
function inpSetFirstPayWay(patPrepayment: number, type) {
  // 判断当前业务场景是住院还是门诊
  if (props.inpOrOutp === 2) {
    //  住院
    if (type) {
      // 查找 payWayDictList 中 dictValue 为 "99" 的元素索引
      const index = payWayDictList.value.findIndex(item => {
        return item.dictValue === "99"
      })
      if (index <= -1) {
        // 如果未找到 dictValue 为 "99" 的元素， 使用 unshift 方法插入元素到数组开头
        payWayDictList.value.unshift(createPaymentMethod(patPrepayment));
      } else {
        // 如果找到 dictValue 为 "99" 的元素，更新该元素的 charges 字段和 disable 字段
        payWayDictList.value[index].charges = patPrepayment;
        payWayDictList.value[index].disable = true;
      }
    } else {
      // 没有预交金
      // 删除 payWayDictList 数组的第一个元素
      payWayDictList.value.splice(0, 1)
      // 判断数组中是否已经存在 dictValue === "1" 的元素
      const existingItem = payWayDictList.value.find(item => item.dictValue === "1");
      if (!existingItem) {
        // 如果不存在 dictValue 为 "1" 的元素，将一个新的支付方式对象添加到数组末尾
        payWayDictList.value.push({dictValue: "1", charges: patPrepayment});
      }
    }
    payWayBlur()
  } else {
    // 门诊
    firstPayWay.value = {dictValue: "1", charges: 0.0};
    // 将 firstPayWay 的值添加到 payWayDictList 数组末尾
    payWayDictList.value.push(firstPayWay.value)
  }
}

/**
 * 住院设置现金
 */
function inpSetCash() {
  let yiJiao: number = 0;
  let thisPayWayDictList = payWayDictList.value.filter(item => item.dictValue !== "1")
  thisPayWayDictList.forEach((list: any) => {
    yiJiao += parseFloat(!list.charges ? 0.0 : list.charges);
  });
  const index = payWayDictList.value.findIndex(item => {
    return item.dictValue === "1"
  })
  // 剩余未交的金额
  const residue = Number((Number(props.totalPrice) - yiJiao).toFixed(2));
  if (index > -1) {
    payWayDictList.value[index].charges = residue
  } else {
    payWayDictList.value.push({dictValue: "1", charges: residue});
  }
  payWayBlur();
}

// 支付方式点击事件
function payWayChange(obj: any, index: number) {
  const indexSelect = dictSelect.value.findIndex((item: any) => {
    return obj === item.dictValue;
  });
  if (indexSelect > -1) {
    payWayDictList.value[index].typeName = dictSelect.value[indexSelect].dictLabel;
    // 设置 字典值，用于统一支付操作字段key值统一
    payWayDictList.value[index].dictValue = obj
    payWayDictList.value[index].moneyType = obj
    payWayDictList.value[index].disable = dictSelect.value[indexSelect].cssClass === 'disable';
  }
  dictSelect.value.forEach((pay: any) => {
    payWayDictList.value.forEach((list: any) => {
      pay.optionDisable = pay.dictValue === list.dictValue;
    });
  });
  payWayBlur();
}

// 增加支付方式点击事件
function addPayWay() {
  dictSelect.value.forEach((pay: any) => {
    payWayDictList.value.forEach((list: any) => {
      if (pay.dictValue === list.dictValue) {
        pay.optionDisable = true;
      }
    });
  });
  let yiJiao: number = 0;
  payWayDictList.value.forEach((list: any) => {
    yiJiao += parseFloat(!list.charges ? 0.0 : list.charges);
  });
  if (props.inpOrOutp === 2) {
    // 住院
    // 剩余未交的金额
    const residue = Number((Number(props.totalPrice - yiJiao)).toFixed(2));
    payWayDictList.value.splice(1, 0, {charges: residue});
  } else {
    // 门诊
    // 剩余未交的金额
    const residue = Number((Number(props.totalPrice) - yiJiao).toFixed(2));
    const lastObj = payWayDictList.value[payWayDictList.value.length - 1];
    if (!lastObj.dictValue) {
      return ElMessage.warning("请填写完已经存在支付方式后，再继续增加");
    }
    payWayDictList.value.push({charges: residue});
  }
  payWayBlur();

}

// 通过下标删除指定的支付方式点击事件
function removePayWay(index: number) {
  dictSelect.value.forEach((pay: any) => {
    if (pay.dictValue === payWayDictList.value[index].dictValue) {
      pay.optionDisable = false;
    }
  });
  payWayDictList.value.splice(index, 1);
  payWayBlur();
}

// 支付方式input金额焦点消失事件
function payWayBlur() {
  let netReceiptsThis: number = 0.0;
  if (props.inpOrOutp === 2) {
    let yiJiao: number = 0;
    let thisPayWayDictList = payWayDictList.value.filter(item => item.dictValue !== "1")
    thisPayWayDictList.forEach((list: any) => {
      yiJiao += parseFloat(!list.charges ? 0.0 : list.charges);
    });
    const index = payWayDictList.value.findIndex(item => {
      return item.dictValue === "1"
    })
    // 剩余未交的金额
    const residue = Number((Number(props.totalPrice) - yiJiao).toFixed(2));
    if (index > -1) {
      payWayDictList.value[index].charges = residue
    } else {
      payWayDictList.value.push({dictValue: "1", charges: residue});
    }
    emits("setNetReceipts", residue.toFixed(2));
  } else {
    // 门诊
    payWayDictList.value.forEach((item: PayWayType) => {
      //@ts-ignore
      netReceiptsThis += parseFloat(!item.charges ? 0.0 : item.charges);
    });
    emits("setNetReceipts", netReceiptsThis.toFixed(2));
  }
}

// 设置初始化金额
function setFirstCost(charges: number) {
  // if (!payWayDictList.value[0].charges) {
  payWayDictList.value[0].charges = Number(charges.toFixed(2));
  // }
}

// 获取支付方式list
function getPayWayDictList() {
  debugger
  return payWayDictList.value;
}

function removePayWayAll() {
  payWayDictList.value = []
  // payWayDictList.value.splice(1);
  // initPayWayDictSelect();
  // payWayBlur();
  // payWayDictList.value[0].charges = 0.00
}


/**
 * 直接传入已经组织好的支付方式
 * @param obj
 */
function settingPayWay(obj: any) {
  payWayDictList.value = []
  let payWayDictListThis: any = []
  let payWaySum: number = 0;
  obj.forEach((item: any) => {
    const dictIndex = dictSelect.value.findIndex((dict: any) => {
      return item.dictValue === dict.dictValue;
    })
    if (dictIndex > -1) {
      let payWay = dictSelect.value[dictIndex]
      payWay.charges = item.charges
      payWay.dictValue = item.dictValue
      payWay.optionDisable = false
      payWayDictListThis.push(payWay)
      payWaySum += Number(payWay.charges)
    }
  })
  payWayDictList.value = payWayDictListThis
  emits("setNetReceipts", payWaySum.toFixed(2));
  // orderByPayWay()
}

// 支付方式合计
const payWayDictListTotal = ref<number>(0)

// 支付方式合计方法
function payWayDictListTotalFun() {
  let costThis: number = 0.0;
  payWayDictList.value.forEach((item: PayWayType) => {
    //@ts-ignore
    costThis += parseFloat(!item.charges ? 0.0 : item.charges);
  });
  payWayDictListTotal.value = costThis
  return costThis
}


/**
 * 处理排序 将cssClass = 'disable' 的支付方式放到数组最前边
 */
function orderByPayWay() {
  payWayDictList.value.sort((a, b) => {
    if ((toRaw(a).cssClass && toRaw(a).cssClass === 'disable') || (toRaw(a).cssClass && toRaw(b).cssClass === 'disable')) {
      return -1;
    } else {
      return 0;
    }
  })
}

/**
 * 根据指定属性对数组元素进行排序的比较函数生成器
 * @param {string} attr - 用于排序的属性名
 * @param {boolean} [rev=true] - 排序方向，true 为升序，false 为降序，默认为升序
 * @returns {function(a: any, b: any): number} - 一个用于数组 sort 方法的比较函数
 */
function sortBy(attr: string, rev: boolean = true): (a: any, b: any) => number {
  // 将布尔值 rev 转换为数字 1 或 -1，用于表示排序方向，若 rev 为 false 则为 -1 表示降序
  const direction = Number(rev) || -1;

  /**
   * 用于数组 sort 方法的比较函数
   * @param {any} a - 数组中的第一个元素
   * @param {any} b - 数组中的第二个元素
   * @returns {number} - 比较结果，小于 0 表示 a 应排在 b 前面，大于 0 表示 a 应排在 b 后面，等于 0 表示两者顺序不变
   */
  return function (a: any, b: any) {
    // 获取元素 a 中指定属性的值
    const valueA = a[attr];
    // 获取元素 b 中指定属性的值
    const valueB = b[attr];
    // 如果 valueA 小于 valueB
    if (valueA < valueB) {
      // 根据排序方向返回相应结果，升序时返回 -1 让 a 排在 b 前
      return direction * -1;
    }
    // 如果 valueA 大于 valueB
    if (valueA > valueB) {
      // 根据排序方向返回相应结果，升序时返回 1 让 a 排在 b 后
      return direction * 1;
    }
    // 如果 valueA 等于 valueB，则返回 0 表示两者顺序不变
    return 0;
  };
}

function tissuePayWayArray(payWayArray: any) {
  payWayDictList.value = []
  let payWayDictListThis: any = []
  payWayArray.forEach((item: any) => {
    const payWayDict = {
      dictValue: item.dictValue,
      charges: item.charges,
      sort: item.sort,
      disable: item.disable,
    }
    payWayDictListThis.push(payWayDict)
  })
  payWayDictList.value = payWayDictListThis.sort(sortBy('sort', true))
}

defineExpose({
  initPayWayDictSelect,
  payWayChange,
  setFirstCost,
  getPayWayDictList,
  payWayBlur,
  removePayWay,
  removePayWayAll,
  inpSetFirstPayWay,
  inpSetCash,
  settingPayWay,
  payWayDictListTotalFun,
  tissuePayWayArray
});
</script>

<style lang="scss" scoped>
:deep(.back-color .el-tooltip__trigger) {
  background-color: rgba(246, 178, 178, 0.8);
}

</style>
